# -*- coding: utf-8 -*-
'''
Created on Nov 4, 2010

Theo review thì dùng Amfast sẽ nhanh hơn 2x->12x so với PyAMF. Trong giai đoạn tutor nên dùng tạm PyAMF
@author: HoangNamHai
'''

import urllib
import re
import cStringIO as StringIO
import logging
import cherrypy
import dbi
import odbc


try: 
    import json
except ImportError: 
    import simplejson as json

try:
    import psyco
    psyco.full()
except ImportError:
    print 'Psyco not found'
    pass
from lxml import etree
# from pyamf.remoting.gateway.wsgi import WSGIGateway

class ZingMeServer:
    # conn=odbc.odbc("DSN=ZingMeGame")
    conn=odbc.odbc("DSN=VMGGame")
    cursor=conn.cursor()
            
    def __init__(self):
        ''' Đoạn init này là dùng cho AMF remote '''
#        services = {
#           'amfphp.echo': self.echo,
#           'amfphp.index': self.index,
#           'amfphp.login': self.login,
#           'amfphp.friends': self.friends,
#           'amfphp.writeWall': self.writeWall,
#        }
#        gateway = WSGIGateway(services, logger=logging, debug=True)
#        cherrypy.tree.graft(gateway, "/gateway/")
        return
    
    def extractWithRegEx(self, pat, matchStr, matchIdx):
        ''' Hàm chạy regex và trả kết quả ở group[matchIdx]. Nếu không có kết quả -> trả về null'''
        try:
            result = ''
            rexp = re.compile(pat)
            m = rexp.search(matchStr)
            if (m!=''):
                result = m.group(matchIdx)
            return result
        except:
            return ''
    
    def buildTreeFromUrl(self, url):
        result = urllib.urlopen(url)
        html = result.read()
        parser = etree.HTMLParser(encoding='utf-8')
        tree = etree.parse(StringIO.StringIO(html), parser)
        return tree
    
    @cherrypy.expose
    def index(self):
        return "Zing Me server v0.1"

    @cherrypy.expose
    def login(self, u='', p='', t='', c='', aaa=''):
        ''' Login
            u = username
            p = password
            t = token
            c = captcha
        '''
        url = 'http://w.me.zing.vn/login?rand=0'
        params = ''
        if (t == ''):
            params = urllib.urlencode({'u': u, 'pp': p})
        else:
            params = urllib.urlencode({'u': u, 'pp': p, 't':t, 'verifycode':c})
        
        html = urllib.urlopen(url, params).read()
        sessionId = self.extractWithRegEx(r"sk=(\w+)", html, 1)      
        cherrypy.log('SessionId = ' + sessionId)
        response = ''
        token = ''
        captchaImg = ''
        try:
            if sessionId != '':
                self.cursor.execute('''
                --try an update
                update TableUser 
                set SessionId = '{0}'
                where UserName = '{1}'
                
                --insert if failed
                if @@rowcount = 0 and @@error = 0
                    insert into TableUser
                           (SessionId, UserName)
                    values ('{0}', '{1}')
                '''.replace('{0}', sessionId).replace('{1}', u))
                cherrypy.log('Insert into MSSQL Ok')
            else:
                cherrypy.log('Invalid username or password')
                parser = etree.HTMLParser(encoding='utf-8')
                tree = etree.parse(StringIO.StringIO(html), parser)
                captchaImg = tree.xpath("//img[@id='sVerifyImg']")[0].get('src')
                token = self.extractWithRegEx(r"token=([\w\.]+)", captchaImg, 1)
                cherrypy.log('Captcha = ' + captchaImg)
                cherrypy.log('Token = ' + token)
            response = json.dumps({'s': sessionId, 'u': u, 't': token, 'c':captchaImg},  separators=(',',':')) # Thêm tham số separators để có compact json
            return response
        except:
            response = json.dumps({'s': sessionId, 'u': u, 't': token, 'c':captchaImg},  separators=(',',':')) # Thêm tham số separators để có compact json
            return response
        
    @cherrypy.expose
    def friends(self, s='', u=''):
        url = 'http://w.me.zing.vn/' + u + '/friend?sk=' + s
        cherrypy.log('Friends: ' + url)
        tree = self.buildTreeFromUrl(url)
        friendList = []
        for friendElem in tree.xpath("//div[@id='main']//div[@class='fr']"):
            friend = {}
            friend['name'] = friendElem.xpath('.//a/strong')[0].text
            friend['username'] = self.extractWithRegEx(r"zing.vn/(.+)/dashboard\?", etree.tostring(friendElem), 1)
            friend['status'] = friendElem.xpath('.//p')[0].text
            friend['img'] = friendElem.xpath('.//img')[0].get('src')
            friendList.append(friend)
        return json.dumps({'friendlist': friendList})
    
    @cherrypy.expose
    def writeWall(self, s='', u='', text=''):
        params = urllib.urlencode({'sk': s, 'fromurl': 'po', 'status': text})
        html = urllib.urlopen('http://w.me.zing.vn/' + u + '/profile/statusupdate?sk=' + s, params).read()
        # return html
        return '{"r":"Done"}'
    
    def echo(self, data):
       """
       This is a function that we will expose.
       """
       return "From server:" + data
   
if __name__ == '__main__':
    _cp_config = {'tools.gzip.on': True}
    global_conf = {
        'global': {
        'server.socket_host': '0.0.0.0',
        'server.socket_port': 8888,
        'tools.encode.on': True,
        'tools.encode.encoding': 'UTF-8'
        },
    }
    config = {
        '/crossdomain.xml': {
            'tools.staticfile.on': True,
            'tools.staticfile.filename': '/home/crossdomain.xml'
        }
    }
    cherrypy.config.update(global_conf)
    # This is where we hook in the WSGIGateway
    cherrypy.quickstart(ZingMeServer(), config=config)
